package com.example.filter;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import javax.servlet.*;
import javax.servlet.http.HttpServletRequest;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.Enumeration;
import java.util.stream.Collectors;

public class RequestLoggingFilter implements Filter {

    private static final Logger logger = LoggerFactory.getLogger(RequestLoggingFilter.class);

    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
        HttpServletRequest httpRequest = (HttpServletRequest) request;

        long startTime = System.currentTimeMillis();

        // 获取请求信息
        String method = httpRequest.getMethod();
        String url = httpRequest.getRequestURL().toString();
        String queryString = httpRequest.getQueryString();
        String fullUrl = (queryString != null) ? url + "?" + queryString : url;

        // 构建日志消息
        StringBuilder logMessage = new StringBuilder();
        logMessage.append(method).append(", ").append(fullUrl);

        // 合并请求头信息到一行
        StringBuilder headersInfo = new StringBuilder();
        Enumeration<String> headerNames = httpRequest.getHeaderNames();
        while (headerNames.hasMoreElements()) {
            String headerName = headerNames.nextElement();
            String headerValue = httpRequest.getHeader(headerName);
            headersInfo.append(headerName).append("=").append(headerValue).append("; ");
        }

        logMessage.append(", Headers: [").append(headersInfo.toString().trim()).append("] - Request started");

        // 获取请求体（仅在POST或PUT请求时）
        if ("POST".equalsIgnoreCase(method) || "PUT".equalsIgnoreCase(method)) {
            String requestBody = new BufferedReader(new InputStreamReader(httpRequest.getInputStream()))
                    .lines()
                    .collect(Collectors.joining("\n")); // 添加换行符
            logMessage.append(", \nBody: \n").append(requestBody);
        }

        // 输出合并后的日志信息
        logger.info(logMessage.toString());

        try {
            // 继续执行过滤器链
            chain.doFilter(request, response);
        } finally {
            long duration = System.currentTimeMillis() - startTime;
            logger.info("Request to {} completed in {} ms", fullUrl, duration);
        }
    }
}
